import java.util.*;
 
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.*;
 
public class LdapC {
 
    DirContext dc = null;
    String account = "man";// 操作LDAP的帐户。默认就是Manager。
    String password = "123";// 帐户Manager的密码。
    String root = "dc=htjs1,dc=net"; // LDAP的根节点的DC
 
    public LdapC() {
        init();
        // add();//添加节点
        // delete("ou=hi,dc=example,dc=com");//删除"ou=hi,dc=example,dc=com"节点
        // modifyInformation("uid=sunyikun1,ou=pt,dc=htjs1,dc=net");//
        // 修改"ou=hi,dc=example,dc=com"属性
        // renameEntry("ou=new,o=neworganization,dc=example,dc=com",
"ou=neworganizationalUnit,o=neworganization,dc=example,dc=com");
        // //重命名节点"ou=new,o=neworganization,dc=example,dc=com"
        // searchInformation("ou=pt,dc=htjs1,dc=net", "", "(objectclass=*)");//
        // 遍历所有根节点
        // searchInformation("o=neworganization,dc=example,dc=com",""," (objectclass=*)");
        //遍历指定节点的分节点
 
 
        close();
    }
 
    public void init() {
        Hashtable env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY,
                "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, "ldap://localhost:389/");
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        env.put(Context.SECURITY_PRINCIPAL, "cn=" + account + "," + root);
        env.put(Context.SECURITY_CREDENTIALS, password);
        try {
            dc = new InitialDirContext(env);// 初始化上下文
            System.out.println("认证成功");// 这里可以改成异常抛出。
        } catch (javax.naming.AuthenticationException e) {
            System.out.println("认证失败");
        } catch (Exception e) {
            System.out.println("认证出错:" + e);
        }
    }
 
    public void close() {
        if (dc != null) {
            try {
                dc.close();
            } catch (NamingException e) {
                System.out.println("NamingException in close():" + e);
            }
        }
    }
 
    public void add() {
        try {
            String newUserName = "hi";
            BasicAttributes attrs = new BasicAttributes();
            BasicAttribute objclassSet = new BasicAttribute("objectClass");
            objclassSet.add("top");
            objclassSet.add("organizationalUnit");
            attrs.put(objclassSet);
            attrs.put("ou", newUserName);
            dc.createSubcontext("ou=" + newUserName + "," + root, attrs);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("Exception in add():" + e);
        }
    }
 
    public void delete(String dn) {
        try {
            dc.destroySubcontext(dn);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("Exception in delete():" + e);
        }
    }
 
    /*
     * 修改记录模块
     */
 
    /*
     * 为DN添加属性
     *
     * @dn:要添加属性的dn
     *
     * @attr:属性的名字
     *
     * @value:属性的值
     */
    public void addAttributeToDN(String dn, String attr, String value)
            throws NamingException {
 
        ModificationItem[] mods = new ModificationItem[1];
 
        Attribute attr0 = new BasicAttribute(attr, value);
        mods[0] = new ModificationItem(DirContext.ADD_ATTRIBUTE, attr0);
 
        dc.modifyAttributes(dn, mods);
    }
 
    /*
     * 修改DN的属性
     *
     * @dn:要修改属性的dn
     *
     * @attr:属性的名字
     *
     * @value:属性的值
     */
    public void editAttributeFromDN(String dn, String attr, String value)
            throws NamingException {
 
        ModificationItem[] mods = new ModificationItem[1];
 
        Attribute attr0 = new BasicAttribute(attr, value);
        mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, attr0);
 
        dc.modifyAttributes(dn, mods);
    }
 
    /*
     * 删除DN的属性
     *
     * @dn:要修改属性的dn
     *
     * @attr:属性的名字
     *
     * @value:属性的值
     */
    public void deleteAttributeFromDN(String dn, String attr, String value)
            throws NamingException {
 
        // 需要一个子树是否为空的判断
 
        ModificationItem[] mods = new ModificationItem[1];
 
        Attribute attr0 = new BasicAttribute(attr, value);
        mods[0] = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, attr0);
 
        dc.modifyAttributes(dn, mods);
    }
 
    public boolean modifyInformation(String dn) {
        try {
            ModificationItem[] mods = new ModificationItem[1];
 
            // for example
            /* 添加属性 */
            // Attribute attr0 = new BasicAttribute("description",
            // "测试");
            // mods[0] = new ModificationItem(DirContext.ADD_ATTRIBUTE,attr0);
 
            /* 修改属性 */
            // Attribute attr0 = new BasicAttribute("description", "陈轶");
            // mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
            // attr0);
 
            /* 删除属性 */
            Attribute attr0 = new BasicAttribute("description", "孙义坤");
            mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, attr0);
            // mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
            // attr0);
            dc.modifyAttributes(dn, mods);
            return true;
        } catch (NamingException ne) {
            ne.printStackTrace();
            System.err.println("Error: " + ne.getMessage());
            return false;
        }
 
    }
 
    /**
     * @param base
     *            :根节点(在这里是"dc=example,dc=com")
     * @param scope
     *            :搜索范围,分为"base"(本节点),"one"(单层),""(遍历)
     * @param filter
     *            :指定子节点(格式为"(objectclass=*)",*是指全部,你也可以指定某一特定类型的树节点)
     */
    public NamingEnumeration search(String base, String scope, String filter) {
 
        SearchControls sc = new SearchControls();// 设置参数问题
        if (scope.equals("base")) {
            sc.setSearchScope(SearchControls.OBJECT_SCOPE);
        } else if (scope.equals("one")) {
            sc.setSearchScope(SearchControls.ONELEVEL_SCOPE);
        } else {
            sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
        }
 
        NamingEnumeration ne = null;
        try {
 
            ne = dc.search(base, filter, sc);
            // Use the NamingEnumeration object to cycle through
            // the result set.
            return ne;
 
        } catch (Exception nex) {
            System.err.println("Error: " + nex.getMessage());
            nex.printStackTrace();
        }
        return null;
    }
 
    /**
     * @param base
     *            :根节点(在这里是"dc=example,dc=com")
     * @param scope
     *            :搜索范围,分为"base"(本节点),"one"(单层),""(遍历)
     * @param filter
     *            :指定子节点(格式为"(objectclass=*)",*是指全部,你也可以指定某一特定类型的树节点)
     */
    public void searchInformation(String base, String scope, String filter) {
 
        SearchControls sc = new SearchControls();// 设置参数问题
        if (scope.equals("base")) {
            sc.setSearchScope(SearchControls.OBJECT_SCOPE);
        } else if (scope.equals("one")) {
            sc.setSearchScope(SearchControls.ONELEVEL_SCOPE);
        } else {
            sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
        }
 
        NamingEnumeration ne = null;
        try {
 
            ne = dc.search(base, filter, sc);
            // Use the NamingEnumeration object to cycle through
            // the result set.
            while (ne.hasMore()) {
                System.out.println();
                SearchResult sr = (SearchResult) ne.next();
                String name = sr.getName();
                if (base != null && !base.equals("")) {
                    System.out.println("entry: " + name + "," + base);
                } else {
                    System.out.println("entry: " + name);
                }
 
                Attributes at = sr.getAttributes();
                NamingEnumeration ane = at.getAll();
 
                while (ane.hasMore()) {
                    Attribute attr = (Attribute) ane.next();
                    String attrType = attr.getID();
                    NamingEnumeration values = attr.getAll();
                    Vector vals = new Vector();
                    // Another NamingEnumeration object, this time
                    // to iterate through attribute values.
                    while (values.hasMore()) {
                        Object oneVal = values.nextElement();
                        if (oneVal instanceof String) {
                            System.out.println(attrType + ": "
                                    + (String) oneVal);
                        } else {
                            System.out.println(attrType + ": "
                                    + new String((byte[]) oneVal));
                        }
                    }
                }
            }
        } catch (Exception nex) {
            System.err.println("Error: " + nex.getMessage());
            nex.printStackTrace();
        }
    }
 
    public boolean renameEntry(String oldDN, String newDN) {
        try {
            dc.rename(oldDN, newDN);
            return true;
        } catch (NamingException ne) {
            System.err.println("Error: " + ne.getMessage());
            return false;
        }
    }
 
    /**
     * 获取指定objectClass的定义
     *
     * @param name
     */
    public void getObjectClassDefinition(String name) {
        try {
            // Get the schema tree root
            DirContext schema = dc.getSchema("");
 
            // Get the schema object for "person"
            DirContext personSchema = (DirContext) schema
                    .lookup("ClassDefinition/" + name);
            Attributes a = personSchema.getAttributes("");
            NamingEnumeration ane = a.getAll();
 
            while (ane.hasMore()) {
                Attribute attr = (Attribute) ane.next();
                String attrType = attr.getID();
                NamingEnumeration values = attr.getAll();
 
                while (values.hasMore()) {
                    Object oneVal = values.nextElement();
                    if (oneVal instanceof String) {
                        System.out.println(attrType + ": " + (String) oneVal);
                    } else {
                        System.out.println(attrType + ": "
                                + new String((byte[]) oneVal));
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    /**
     * 获取指定DN的objectClass定义
     *
     * @param DN
     */
    public void getDNObjectClassDefinition(String DN) {
        try {
            // Get context containing class definitions for the "cn=Ted Geisel"
            // entry
            DirContext tedClasses = dc.getSchemaClassDefinition(DN);
 
            // Enumerate the class definitions
            NamingEnumeration enum1 = tedClasses.search("", null);
            while (enum1.hasMore()) {
                Object o = enum1.next();
                System.out.println(((SearchResult) o).getName());
 
                Attributes a = ((SearchResult) o).getAttributes();
                NamingEnumeration ane = a.getAll();
 
                while (ane.hasMore()) {
                    Attribute attr = (Attribute) ane.next();
                    String attrType = attr.getID();
                    NamingEnumeration values = attr.getAll();
 
                    while (values.hasMore()) {
                        Object oneVal = values.nextElement();
                        if (oneVal instanceof String) {
                            System.out.println(attrType + ": "
                                    + (String) oneVal);
                        } else {
                            System.out.println(attrType + ": "
                                    + new String((byte[]) oneVal));
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    /**
     * 获取指定名字的Attribute定义
     *
     * @param name
     */
    public void getAttributeDefinition(String name) {
        try {
            // Get the schema tree root
            DirContext schema = dc.getSchema("");
 
            // Get the schema object for "person"
            DirContext personSchema = (DirContext) schema
                    .lookup("AttributeDefinition/" + name);
            Attributes a = personSchema.getAttributes("");
            NamingEnumeration ane = a.getAll();
 
            while (ane.hasMore()) {
                Attribute attr = (Attribute) ane.next();
                String attrType = attr.getID();
                NamingEnumeration values = attr.getAll();
 
                while (values.hasMore()) {
                    Object oneVal = values.nextElement();
                    if (oneVal instanceof String) {
                        System.out.println(attrType + ": " + (String) oneVal);
                    } else {
                        System.out.println(attrType + ": "
                                + new String((byte[]) oneVal));
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    /**
     * 获取指定DN中指定名字的Attribute定义
     *
     * @param DN
     * @param name
     */
    public void getDNAttributeDefinition(String DN, String name) {
        try {
            // Get an attribute of that type
            Attributes attrs = dc.getAttributes(DN, new String[] { name });
            Attribute cnAttr = attrs.get(name);
 
            // Get its attribute type definition
            DirContext cnSchema = cnAttr.getAttributeDefinition();
            // Get cnSchema's attributes
            Attributes cnAttrs = cnSchema.getAttributes("");
 
            NamingEnumeration ane = cnAttrs.getAll();
            while (ane.hasMore()) {
                Attribute attr = (Attribute) ane.next();
                String attrType = attr.getID();
                NamingEnumeration values = attr.getAll();
 
                while (values.hasMore()) {
                    Object oneVal = values.nextElement();
                    if (oneVal instanceof String) {
                        System.out.println(attrType + ": " + (String) oneVal);
                    } else {
                        System.out.println(attrType + ": "
                                + new String((byte[]) oneVal));
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    public static void main(String[] args) {
        new LdapC();
    }
}